package com.xoa.controller.wps;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xoa.controller.wps.FileDTO;
import com.xoa.controller.wps.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.xoa.util.systeminfo.Base64.encodeBase64String;

/**
 * @author zm
 * 文件相关回调接口
 */
@RestController
@RequestMapping("v1/3rd")
public class FileCallBackController {


    /**
     * 获取文件元数据
     */
    @GetMapping("/file/info")
    public ResponseEntity<Object> getFileInfo(
            String _w_fname, String _w_fpath,String _w_fileid) {
        try {

//            String testFile = "http://103.72.172.31:30035/download?AID=15509&MODULE=email&COMPANY=xoa1001&YM=2007&ATTACHMENT_ID=841478147&ATTACHMENT_NAME=111.docx&FILESIZE=12.6%20KB";
//            String testFile2 = "http://xoa.gaosubo.com/download?AID=9031&MODULE=email&COMPANY=xoa1001&YM=2006&ATTACHMENT_ID=1943900307&ATTACHMENT_NAME=%25E6%25B3%259B%25E5%25BE%25AE%25E5%258D%258F%25E5%2590%258C%25E5%258A%259E%25E5%2585%25AC%25E5%25B9%25B3%25E5%258F%25B0e-office10%25E5%258A%259F%25E8%2583%25BD%25E6%25B8%2585%25E5%258D%2595.docx";
//            Map<String, Object> map = this.getWebFileInfo(testFile);

            Map<String, String> paramMap = new HashMap<>();
            String fileType =  FileUtil.getFileTypeByName(_w_fname);
            String fileTypeCode = "/"+FileUtil.getFileTypeCode(fileType)+"/";
            paramMap.put("_w_appid", "3852e279dd0c4177b0518d70f5b3a9c3");
            paramMap.put("_w_fname", _w_fname);
            paramMap.put("_w_fpath", _w_fpath);
            paramMap.put("_w_fileid", _w_fileid);
            Map<String, Object> map = this.getWebFileInfo(_w_fname,_w_fpath,_w_fileid);
            String signature = getSignature(paramMap, "c53aa7478ce54536aa26f11c3046d6b5");
            map.put("signature", fileTypeCode+getUrlParam(paramMap)+_w_fileid+"?" + "&_w_signature=" + signature);
            return Response.success(map);
        } catch (Exception e) {
            return Response.bad("获取文件元数据异常");
        }
    }


    /**
     * 回调通知
     */
    @PostMapping("/file/onnotify")
    public ResponseEntity<Object> onNotify(
            @RequestBody JSONObject obj
    ) {
        // TODO
        // 返回数据暂不处理
        return Response.success();
    }

    public static void main(String args[]) throws UnsupportedEncodingException {
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("_w_appid", "3852e279dd0c4177b0518d70f5b3a9c3");
        paramMap.put("_w_fname", "222.docx");
        //paramMap.put("_w_userid", "id1000");
        String signature = getSignature(paramMap, "c53aa7478ce54536aa26f11c3046d6b5");

        System.out.println(getUrlParam(paramMap) + "&_w_signature=" + signature);
    }

    private static String getUrlParam(Map<String, String> params) throws UnsupportedEncodingException {
        StringBuilder builder = new StringBuilder();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            if (builder.length() > 0) {
                builder.append('&');
            }
            builder.append(URLEncoder.encode(entry.getKey(), "utf-8")).append('=').append(URLEncoder.encode(entry.getValue(), "utf-8"));
        }
        return builder.toString();
    }

    private static String getSignature(Map<String, String> params, String appSecret) {
        List<String> keys = new ArrayList();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            keys.add(entry.getKey());
        }

        // 将所有参数按key的升序排序
        Collections.sort(keys, new Comparator<String>() {
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });

        // 构造签名的源字符串
        StringBuilder contents = new StringBuilder("");
        for (String key : keys) {
            if (key == "_w_signature") {
                continue;
            }
            contents.append(key + "=").append(params.get(key));
            System.out.println("key:" + key + ",value:" + params.get(key));
        }
        contents.append("_w_secretkey=").append(appSecret);

        // 进行hmac sha1 签名
        byte[] bytes = hmacSha1(appSecret.getBytes(), contents.toString().getBytes());
        //字符串经过Base64编码
        String sign = encodeBase64String(bytes);
        try {
            sign = URLEncoder.encode(sign, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        System.out.println(sign);
        return sign;
    }

    public static byte[] hmacSha1(byte[] key, byte[] data) {
        try {
            SecretKeySpec signingKey = new SecretKeySpec(key, "HmacSHA1");
            Mac mac = Mac.getInstance(signingKey.getAlgorithm());
            mac.init(signingKey);
            return mac.doFinal(data);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }
        return null;
    }

    private Map<String, Object> getWebFileInfo( String fname,String filePath,String fileid) {

        // 构建默认user信息
        UserDTO wpsUser = new UserDTO(
                "1", "我", "read", ""
        );

        int fileSize = 0;
        try {
            fileSize = FileUtil.getFileLength(filePath)/1000;
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 构建文件
        FileDTO file = new FileDTO(fileid,fname,
                1, fileSize, "-1", new Date().getTime(), filePath,
                // 默认设置为无水印，只读权限
                new UserAclBO(), new WatermarkBO()
        );
        Map map = new HashMap<String, Object>();
        map.put("file", file);
        map.put("user", wpsUser);
        return map;
    }



}